// utilregEx.h: interface for the CUTILregEx class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_UTILREGEX_H__38A46F21_AA90_11D4_A250_00A0CC502E02__INCLUDED_)
#define AFX_UTILREGEX_H__38A46F21_AA90_11D4_A250_00A0CC502E02__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <windows.h>

class CUTILregEx  
	{
	public:
		enum CopyOptions
			{
			COPY_VALUES_ONLY	= 0,	// copy values only
			COPY_RECURSIVELY	= 1,	// copy values and subkeys recursively
			};

		CUTILregEx(const HKEY hKeyRoot, LPCTSTR lpKey, REGSAM samDesired = (KEY_READ|KEY_WRITE));
		CUTILregEx(LPCTSTR lpKey, REGSAM samDesired = (KEY_READ|KEY_WRITE));
		CUTILregEx(BOOL bTryBaseKey=TRUE, REGSAM samDesired = (KEY_READ|KEY_WRITE));
		virtual ~CUTILregEx();

		HRESULT CreateKey(				// create keys recursively
			HKEY hKey,					// handle to open key
			LPCTSTR lpSubKey,			// subkey name
			PHKEY phkResult,			// key handle 
			DWORD dwOptions = REG_OPTION_NON_VOLATILE,	// special options
			REGSAM samDesired = (KEY_READ|KEY_WRITE)			// desired security access
			);
		HRESULT CopyValues(				// copy values
			HKEY hKeyDst,
			HKEY hKeySrc,
			CopyOptions Options	= COPY_RECURSIVELY
			);
		HRESULT EnumerateSubKeys(		// walk through subkey names...
			DWORD *pdwLastIdx,
			LPTSTR lpSubKeyName,
			DWORD dwNameMaxLen
			);
		// return: ERROR_SUCCES on success
		HRESULT SetValue(LPCTSTR lpValueName, long nValue, BOOL bSetOnlyWhenExisted=FALSE);
		HRESULT SetValue(LPCTSTR lpValueName, int nValue, BOOL bSetOnlyWhenExisted=FALSE);
		HRESULT SetValue(LPCTSTR lpValueName, ULONG nValue, BOOL bSetOnlyWhenExisted=FALSE);
		HRESULT SetValue(LPCTSTR lpValueName, UINT nValue, BOOL bSetOnlyWhenExisted=FALSE);
		HRESULT SetValue(LPCTSTR lpValueName, char* szValue);
		HRESULT SetValue(LPCTSTR lpValueName, UCHAR* szValue);
		HRESULT SetValue(LPCTSTR lpValueName, LPCTSTR szValue, BOOL bScramble = FALSE);
		HRESULT SetValue(LPCTSTR lpValueName, LONGLONG llValue);
		HRESULT SetBinValue(LPCTSTR lpValueName, LPBYTE lpValue, DWORD dwLen);
		HRESULT SetBinValue(LPCTSTR lpValueName, LPCTSTR lpValue, BOOL bScramble = FALSE);

		HRESULT GetValue(LPCTSTR lpValueName, long*		lpValue, long nDefault);
		HRESULT GetValue(LPCTSTR lpValueName, long*		lpValue);
		HRESULT GetValue(LPCTSTR lpValueName, int*		lpValue, int nDefault);
		HRESULT GetValue(LPCTSTR lpValueName, int*		lpValue);
		HRESULT GetValue(LPCTSTR lpValueName, ULONG*	lpValue, ULONG nDefault);
		HRESULT GetValue(LPCTSTR lpValueName, ULONG*	lpValue);
		HRESULT GetValue(LPCTSTR lpValueName, UINT*		lpValue, UINT nDefault);
		HRESULT GetValue(LPCTSTR lpValueName, UINT*		lpValue);
		HRESULT GetValue(LPCTSTR lpValueName, LONGLONG* pllValue, LONGLONG llDefault);
		HRESULT GetValue(LPCTSTR lpValueName, LONGLONG* pllValue);
		HRESULT GetValue(LPCTSTR lpValueName, char*		lpValue, LPDWORD lpdwLen);
		HRESULT GetValue(LPCTSTR lpValueName, UCHAR*	lpValue, LPDWORD lpdwLen);
		HRESULT GetValue(LPCTSTR lpValueName, LPCTSTR	lpValue, LPDWORD lpdwLen, BOOL bDescramble = FALSE);
		HRESULT GetBinValue(LPCTSTR lpValueName, LPCTSTR	lpValue, LPDWORD lpdwLen, BOOL bDescramble = FALSE);
		HRESULT GetBinValue(LPCTSTR lpValueName, LPBYTE	lpValue, LPDWORD lpdwLen);

		HRESULT	DeleteValue(LPCTSTR lpValueName);
		HRESULT	DeleteSubKey(LPCTSTR lpSubKey, BOOL bRecursive = FALSE);

		static	void WINAPI SetRegKeyBase(LPCTSTR baseKey);
		static	void WINAPI GetRegKeyBase(LPTSTR key, int bufLen);

		HKEY	GetHKEY() const;

		// operator overloaded functions
		CUTILregEx& operator=(LPCTSTR pszName);


	protected:
		BOOL		m_bKeyOpen;			// is there currently a root key open?
		BOOL		m_bAllowCreate;		// should we be able to create entries?
		HKEY		m_hKeyRoot;			// the root key (usually HKCU)
		HKEY		m_hKey;				// the key for this object (i.e. HKCU\Software\CompanyName\AppName)
		HKEY		m_hLmKey;			// The HKLM version of m_hKey (used when HKCU does not have the data)
		REGSAM		m_samOpenSecurity;	// security mask for opening a reg key (added for XP sensitivity)
		TCHAR		m_lpKey[MAX_PATH];

		HRESULT SetDW(LPCTSTR lpValueName, DWORD dwValue, BOOL bSetOnlyWhenExisted=FALSE);
		HRESULT GetDW(LPCTSTR lpValueName, LPDWORD lpValue, DWORD dwDefault);
		HRESULT SetSZ(LPCTSTR lpValueName, LPCTSTR lpValue);
		HRESULT GetSZ(LPCTSTR lpValueName, LPCTSTR lpValue, LPDWORD lpdwLen);
		void DeleteKeyRecursive(HKEY hKey);
			
	private:
		HRESULT Init(LPCTSTR lpKey);
		void Descramble(LPTSTR szSource, DWORD dwSize);
		void Scramble(LPCTSTR szSource, LPTSTR sTarget);
		TCHAR GetScrambledCode(INT nOrder);
		TCHAR GetRandom();
		_inline static DWORD timeGetTime()
			{
#ifdef _WIN32
			SYSTEMTIME a; GetLocalTime(&a);	  
			return (((a.wHour*60)+a.wMinute)*60+a.wSecond)*1000 + a.wMilliseconds; 
#else
			return ::timeGetTime();
#endif
			}
	};


#endif // !defined(AFX_UTILREGEX_H__38A46F21_AA90_11D4_A250_00A0CC502E02__INCLUDED_)
